import { FormInstance } from 'antd';
import debounce from 'lodash/debounce';
import { makeAutoObservable, runInAction } from 'mobx';
import certificateApi from '../../api/certificateApi';
import taskApi from '../../api/taskApi';

export default class Task {

  loading: boolean;
  detailLoading: boolean;
  saving: boolean;
  data: any[];
  current: number;
  pageSize: number;
  total: number;
  record: any;
  conditions: object;
  taskDetailLoading: boolean;
  taskDetails: any[];
  taskDetailCurrent: number;
  taskDetailPageSize: number;
  taskDetailTotal: number;
  sourceDepartemnts: any[];
  targetDepartemnts: any[];
  sourceExpandedKeys: any[];
  targetExpandedKeys: any[];

  constructor() {
    this.loading = false;
    this.detailLoading = false;
    this.saving = false;
    this.data = [];
    this.current = 0;
    this.pageSize = 10;
    this.total = 0;
    this.record = null;
    this.conditions = this.getDefaultConditions();
    this.taskDetailLoading = false;
    this.taskDetails = [];
    this.taskDetailCurrent = 0;
    this.taskDetailPageSize = 10;
    this.taskDetailTotal = 0;
    this.sourceDepartemnts = [];
    this.targetDepartemnts = [];
    this.sourceExpandedKeys = [];
    this.targetExpandedKeys = [];
    makeAutoObservable(this);
  }

  async fetchData(keyword: string, company: any[], appType: string, active: string, frequency: string, lastExecuteStatus: string,
    pageNumber: number) {
    if (this.loading) {
      return;
    }

    runInAction(() => {
      this.loading = true;
    });
    const companyId: string = company?.length > 0 ? company[0].value : '';
    const res: any = await taskApi.query(keyword, companyId, appType, active, frequency, lastExecuteStatus, pageNumber, this.pageSize);
    const list: any[] = res.data?.list || [];
    runInAction(() => {
      this.data = list;
      this.current = res.data?.current || 0;
      this.total = res.data?.total || 0;
      this.loading = false;
      this.conditions = {
        keyword,
        company,
        appType,
        active,
        frequency,
        lastExecuteStatus,
        pageNumber
      };
    });
  }

  async fetchDetail(id: string, callback: (data: any) => void | undefined) {
    if (this.detailLoading) {
      return;
    }

    runInAction(() => {
      this.detailLoading = true;
    });
    const res: any = await taskApi.find(id);
    const data: any = res.data || {};
    runInAction(() => {
      this.record = data;
      this.detailLoading = false;
      if (callback) {
        callback(data);
      }
    });
    this.fetchTaskDetails('', '', '', true, 0);
  }

  async fetchTaskDetails(startDate: string, endDate: string, executeStatus: string, reverseOrder: boolean, pageNumber: number) {
    if (this.taskDetailLoading) {
      return;
    }

    runInAction(() => {
      this.taskDetailLoading = true;
    });
    const res: any = await taskApi.details(this.record?.task?.id || '<empty>', startDate, endDate, executeStatus, reverseOrder, pageNumber, this.taskDetailPageSize);
    const list: any[] = res.data?.list || [];
    runInAction(() => {
      this.taskDetails = list;
      this.taskDetailCurrent = res.data?.current || 0;
      this.taskDetailTotal = res.data?.total || 0;
      this.taskDetailLoading = false;
    })
  }

  async fetchDepartments(target: boolean, company: any[], appType: string) {
    const companyId: string = company?.length > 0 ? company[0].value : '';
    this.setDepartments(target, []);
    if (companyId && appType) {
      const res: any = await certificateApi.testByCompany(companyId, appType);
      this.setDepartments(target, res.data || []);
    }
  }

  saveData(values: any) {
    this.setSaving(true);
    const data: any = {
      id: null,
      ...values
    };
    data.retryInterval = data.retryInterval || 0;
    return taskApi.save(data);
  }

  updateData(field: string, value: any) {
    const id: string = this.record.task?.id || '';
    return taskApi.update(id, field, value);
  }

  deleteData() {
    return taskApi.delete(this.record?.task?.id || '<empty>');
  }

  setPageSize(pageSize: number) {
    runInAction(() => {
      this.pageSize = pageSize;
    });
  }

  setSaving(saving: boolean) {
    runInAction(() => {
      this.saving = saving;
    });
  }

  setRecord(record: any) {
    runInAction(() => {
      this.record = record;
    });
  }

  setTaskDetailPageSize(pageSize: number) {
    runInAction(() => {
      this.taskDetailPageSize = pageSize;
    });
  }

  setDepartments(target: boolean, departments: any[]) {
    runInAction(() => {
      const keys: any[] = [];
      this.getDepartemntParentKeys(departments, keys);
      if (target) {
        this.targetDepartemnts = departments;
        this.targetExpandedKeys = keys;
      } else {
        this.sourceDepartemnts = departments;
        this.sourceExpandedKeys = keys;
      }
    });
  }

  setExpandedKeys(target: boolean, expandedKeys: string[]) {
    runInAction(() => {
      if (target) {
        this.targetExpandedKeys = expandedKeys;
      } else {
        this.sourceExpandedKeys = expandedKeys;
      }
    });
  }

  getDepartemntParentKeys(departments: any[], keys: any[]) {
    if (departments && departments.length) {
      departments.forEach((item: any) => {
        keys.push(item.key);
        if (item.children && item.children.length) {
          this.getDepartemntParentKeys(item.children, keys);
        }
      });
    }
  }

  getDepartmentNameById(target: boolean, id: string) {
    const departments: any[] = target ? this.targetDepartemnts : this.sourceDepartemnts;
    const findDepartemnt = (departments: any[], id: string) => {
      let item: any = null;
      for (let i = 0, count = departments.length; i < count;i++) {
        if (departments[i].key === id) {
          item = departments[i];
          break;
        } else if (departments[i].children && departments[i].children.length) {
          item = findDepartemnt(departments[i].children, id);
          if (item) {
            break;
          }
        }
      }
      return item;
    };
    const item: any = findDepartemnt(departments, id);
    return item ? item.title : '';
  }

  getDefaultConditions() {
    return {
      keyword: '',
      company: [],
      appType: '',
      active: '',
      frequency: '',
      lastExecuteStatus: '',
      pageNumber: 0
    };
  }

  resetConditions(form: FormInstance<any>) {
    runInAction(() => {
      this.conditions = this.getDefaultConditions();
      debounce(() => form.resetFields(), 50)();
    });
  }

  setConditions(conditions: any) {
    runInAction(() => {
      this.conditions = conditions;
    });
  }

};
